﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 滑块控件
    /// </summary>
    [Description("滑块控件")]
    [DefaultProperty("Value")]
    [DefaultEvent("ValueChanged")]
    [TypeConverter(typeof(PropertyOrderConverter))]
    [Designer(typeof(TrackBarPlusDesigner))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(TrackBarPlus), "Controls.TrackBarPlus.Resources.TrackBarPlus.bmp")]
    public class TrackBarPlus : DpiControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(TrackBarPlus)).GetName().Name, typeof(TrackBarPlus).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled= SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        private static readonly object EventValueChanged = new object();
        /// <summary>
        /// Value值更改事件
        /// </summary>
        [Description("Value值更改事件")]
        public event EventHandler ValueChanged
        {
            add { Events.AddHandler(EventValueChanged, value); }
            remove { Events.RemoveHandler(EventValueChanged, value); }
        }


        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler FontChanged
        {
            add { base.FontChanged += value; }
            remove { base.FontChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Click
        {
            add { base.Click += value; }
            remove { base.Click -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseClick
        {
            add { base.MouseClick += value; }
            remove { base.MouseClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        #endregion

        #region 新增属性

        private TrackBarPlusStylePattern stylePattern = TrackBarPlusStylePattern.Excircle;
        /// <summary>
        /// 风格模式
        /// </summary>
        [Description("风格模式")]
        [Category("杂项")]
        [PropertyOrder(-198)]
        [DefaultValue(TrackBarPlusStylePattern.Excircle)]
        public TrackBarPlusStylePattern StylePattern
        {
            get { return this.stylePattern; }
            set
            {
                if (this.stylePattern == value)
                    return;

                this.stylePattern = value;
                this.UpdateAutoControlSize();
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private TrackBarPlusOrientation orientation = TrackBarPlusOrientation.HorizontalTop;
        /// <summary>
        /// 显示方位
        /// </summary>
        [Description("显示方位")]
        [Category("杂项")]
        [PropertyOrder(-196)]
        [DefaultValue(TrackBarPlusOrientation.HorizontalTop)]
        public TrackBarPlusOrientation Orientation
        {
            get { return this.orientation; }
            set
            {
                if (this.orientation == value)
                    return;

                this.orientation = value;
                this.UpdateAutoControlSize();
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private TrackObject track;
        /// <summary>
        /// 轨道
        /// </summary>
        [Description("轨道")]
        [Category("杂项")]
        [PropertyOrder(-175)]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TrackObject Track
        {
            get
            {
                if (this.track == null)
                    this.track = new TrackObject(this);
                return this.track;
            }
        }

        private ThumbObject thumb;
        /// <summary>
        /// 拇指
        /// </summary>
        [Description("拇指")]
        [Category("杂项")]
        [PropertyOrder(-173)]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ThumbObject Thumb
        {
            get
            {
                if (this.thumb == null)
                    this.thumb = new ThumbObject(this);
                return this.thumb;
            }
        }

        private MarkObject mark;
        /// <summary>
        /// 刻度
        /// </summary>
        [Description("刻度")]
        [Category("杂项")]
        [PropertyOrder(-170)]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public MarkObject Mark
        {
            get
            {
                if (this.mark == null)
                    this.mark = new MarkObject(this);
                return this.mark;
            }
        }

        private double smallChange = 1;
        /// <summary>
        /// 键盘Up、Down 或 鼠标滚轮上下键移动 最小间隔值
        /// </summary>
        [Description("键盘Up、Down 或 鼠标滚轮上下键移动 最小间隔值")]
        [Category("杂项")]
        [PropertyOrder(-166)]
        [DefaultValue(1D)]
        public double SmallChange
        {
            get { return this.smallChange; }
            set
            {
                if (this.smallChange == value || value <= 0)
                    return;

                this.smallChange = value;
            }
        }

        private double maxValue = 100;
        /// <summary>
        /// 最大值
        /// </summary>
        [Description("最大值")]
        [Category("杂项")]
        [PropertyOrder(-164)]
        [DefaultValue(100D)]
        public double MaxValue
        {
            get { return this.maxValue; }
            set
            {
                if (this.maxValue == value)
                    return;

                this.maxValue = value;
                if (value < this.minValue)
                {
                    this.minValue = value;
                }
                if (this.value < this.minValue)
                {
                    this.value = this.minValue;
                }
                if (this.value > this.maxValue)
                {
                    this.value = this.maxValue;
                }

                this.InitializeElement();
                this.Invalidate();
            }
        }

        private double minValue = 0;
        /// <summary>
        /// 最小值
        /// </summary>
        [Description("最小值")]
        [Category("杂项")]
        [PropertyOrder(-162)]
        [DefaultValue(0D)]
        public double MinValue
        {
            get { return this.minValue; }
            set
            {
                if (this.minValue == value)
                    return;

                this.minValue = value;
                if (value > this.maxValue)
                {
                    this.maxValue = value;
                }
                if (this.value < this.minValue)
                {
                    this.value = this.minValue;
                }
                if (this.value > this.maxValue)
                {
                    this.value = this.maxValue;
                }

                this.InitializeElement();
                this.Invalidate();
            }
        }

        private double value = 0;
        /// <summary>
        /// 值
        /// </summary>
        [Description("值")]
        [Category("杂项")]
        [PropertyOrder(-160)]
        [DefaultValue(0D)]
        public double Value
        {
            get { return this.value; }
            set
            {
                if (this.minValue > value || value > this.maxValue)
                {
                    throw new ArgumentOutOfRangeException("“Value”无效。“Value”应介于 'MinValue' 和 'MaxValue' 之间。");
                }

                if (this.value == value)
                    return;

                this.value = value;
                this.InitializeElement();
                this.Invalidate();

                this.OnValueChanged(EventArgs.Empty);
            }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(200, 24); }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Padding Padding
        {
            get { return base.Padding; }
            set { base.Padding = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get { return base.Text; }
            set { base.Text = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override Font Font
        {
            get { return base.Font; }
            set { base.Font = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
            get { return this.StyleAppearance.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.StyleAppearance.Normal.ThumbBackColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 当前鼠标已按下的对象
        /// </summary>
        private bool mousedownobject = false;
        /// <summary>
        /// 当前鼠标已按下的对象的value
        /// </summary>
        private decimal mousedownobjectvalue = -1;
        /// <summary>
        /// 当前鼠标已按下的坐标
        /// </summary>
        private Point mousedownpoint = Point.Empty;

        /// <summary>
        /// 控件内边距
        /// </summary>
        private int contentPadding = 2;

        /// <summary>
        /// 滑杆rect
        /// </summary>
        private RectangleF poleRect;
        /// <summary>
        /// 滑块rect
        /// </summary>
        private RectangleF lumpRect;
        /// <summary>
        /// 滑块Path
        /// </summary>
        private GraphicsPath lumpPath;

        /// <summary>
        /// 滑块开始坐标(滑块中心为参考点)
        /// </summary>
        private float Lump_Start_Point;

        /// <summary>
        /// 滑块结束坐标(滑块中心为参考点)
        /// </summary>
        private float Lump_End_Point;

        #endregion

        public TrackBarPlus()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, true);
            SetStyle(ControlStyles.StandardDoubleClick, false);

            this.InitializeElement();
            this.OnSkinChanged();

        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.SetBoundsCore(this.Location.X, this.Location.Y, this.Width, this.Height, BoundsSpecified.All);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;

            int scale_contentPadding = (int)Math.Ceiling(this.contentPadding * this.ScaleDpi);
            Rectangle content_rect = new Rectangle(scale_contentPadding, scale_contentPadding, this.ClientRectangle.Width - scale_contentPadding * 2, this.ClientRectangle.Height - scale_contentPadding * 2);
            bool ishorizontal = (this.Orientation == TrackBarPlusOrientation.HorizontalTop || this.Orientation == TrackBarPlusOrientation.HorizontalBottom);

            Color pole_back_color = Color.Empty;
            Color pole_value_color = Color.Empty;
            Color lump_border_color = Color.Empty;
            Color lump_back_color = Color.Empty;
            Color mark_line_color = Color.Empty;
            if (!this.Enabled)
            {
                pole_back_color = this.StyleAppearance.Disabled.TrackBackColor;
                pole_value_color = this.StyleAppearance.Disabled.TrackValueColor;
                lump_border_color = this.StyleAppearance.Disabled.ThumbBorderColor;
                lump_back_color = this.StyleAppearance.Disabled.ThumbBackColor;
                mark_line_color = this.StyleAppearance.Disabled.MarkLineColor;
            }
            else
            {
                pole_back_color = this.StyleAppearance.Normal.TrackBackColor;
                pole_value_color = this.StyleAppearance.Normal.TrackValueColor;
                lump_border_color = this.StyleAppearance.Normal.ThumbBorderColor;
                lump_back_color = this.StyleAppearance.Normal.ThumbBackColor;
                mark_line_color = this.StyleAppearance.Normal.MarkLineColor;
            }
            if (this.StylePattern == TrackBarPlusStylePattern.Excircle)
            {
                //滑杆背景色
                if (this.Track.BackGradualColors.Count > 0)
                {
                    RectangleF pole_back_sb_rect = RectangleF.Empty;
                    if (ishorizontal)
                    {
                        pole_back_sb_rect = new RectangleF(this.poleRect.X - 1, this.poleRect.Y, this.poleRect.Width + 1, this.poleRect.Height);
                    }
                    else
                    {
                        pole_back_sb_rect = new RectangleF(this.poleRect.X, this.poleRect.Y - 1, this.poleRect.Width, this.poleRect.Height + 1);
                    }
                    LinearGradientBrush pole_back_lgb = this.GetLinearGradientBrush(this.Track.BackGradualColors, pole_back_sb_rect, (ishorizontal ? 0f : 270f));
                    g.FillRectangle(pole_back_lgb, this.poleRect);
                    pole_back_lgb.Dispose();
                }
                else
                {
                    SolidBrush pole_back_sb = new SolidBrush(pole_back_color);
                    g.FillRectangle(pole_back_sb, this.poleRect);
                    pole_back_sb.Dispose();
                }

                //滑杆值色
                if (this.Track.ValueGradualColors.Count > 0)
                {
                    RectangleF pole_value_sb_rect = RectangleF.Empty;
                    RectangleF pole_value_rect = RectangleF.Empty;
                    if (ishorizontal)
                    {
                        pole_value_sb_rect = new RectangleF(this.poleRect.X - 1, this.poleRect.Y, this.poleRect.Width + 1, this.poleRect.Height);
                        pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, (this.lumpRect.X + this.lumpRect.Width / 2 - this.poleRect.X), this.poleRect.Height);
                    }
                    else
                    {
                        pole_value_sb_rect = new RectangleF(this.poleRect.X, this.poleRect.Y - 1, this.poleRect.Width, this.poleRect.Height + 1);
                        pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Width, (this.lumpRect.Y + this.lumpRect.Height / 2 - this.poleRect.Y));
                    }

                    LinearGradientBrush pole_value_back_lgb = this.GetLinearGradientBrush(this.Track.ValueGradualColors, pole_value_sb_rect, (ishorizontal ? 0f : 270f));
                    g.FillRectangle(pole_value_back_lgb, pole_value_rect);
                    pole_value_back_lgb.Dispose();
                }
                else
                {
                    if (pole_value_color != Color.Empty && pole_value_color.A != 0)
                    {
                        RectangleF pole_value_rect = RectangleF.Empty;
                        if (ishorizontal)
                        {
                            pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, (this.lumpRect.X + this.lumpRect.Width / 2 - this.poleRect.X), this.poleRect.Height);
                        }
                        else
                        {
                            pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Width, (this.lumpRect.Y + this.lumpRect.Height / 2 - this.poleRect.Y));
                        }
                        SolidBrush pole_value_back_sb = new SolidBrush(pole_value_color);
                        g.FillRectangle(pole_value_back_sb, pole_value_rect);
                        pole_value_back_sb.Dispose();
                    }
                }

                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.High;

                //滑块背景
                SolidBrush lump_back_sb = new SolidBrush(lump_back_color);
                g.FillPath(lump_back_sb, this.lumpPath);
                lump_back_sb.Dispose();

                //滑块边框
                Pen lump_border_pen = new Pen(lump_border_color);
                g.DrawPath(lump_border_pen, this.lumpPath);
                lump_border_pen.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    RectangleF activate_rectf = new RectangleF(this.lumpRect.X + 3, this.lumpRect.Y + 3, this.lumpRect.Width - 6, this.lumpRect.Height - 6);
                    Pen activate_border_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawEllipse(activate_border_pen, activate_rectf);
                    activate_border_pen.Dispose();
                }

            }
            else if (this.StylePattern == TrackBarPlusStylePattern.InnerCircle)
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.High;

                //滑杆背景色
                if (this.Track.BackGradualColors.Count > 0)
                {
                    GraphicsPath pole_back_gp = new GraphicsPath();
                    RectangleF pole_back_rect = RectangleF.Empty;
                    if (ishorizontal)
                    {
                        pole_back_rect = new RectangleF(this.poleRect.X - 1, this.poleRect.Y, this.poleRect.Width + 1, this.poleRect.Height);
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Height, this.poleRect.Height), 90, 180);
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.Right - this.poleRect.Height, this.poleRect.Top, this.poleRect.Height, this.poleRect.Height), 270, 180);
                    }
                    else
                    {
                        pole_back_rect = new RectangleF(this.poleRect.X, this.poleRect.Y - 1, this.poleRect.Width, this.poleRect.Height + 1);
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Width, this.poleRect.Width), 180, 180);
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Bottom - this.poleRect.Width, this.poleRect.Width, this.poleRect.Width), 0, 180);
                    }
                    LinearGradientBrush pole_back_lgb = this.GetLinearGradientBrush(this.Track.BackGradualColors, pole_back_rect, (ishorizontal ? 0f : 270f));
                    g.FillPath(pole_back_lgb, pole_back_gp);
                    pole_back_lgb.Dispose();
                    pole_back_gp.Dispose();
                }
                else
                {
                    GraphicsPath pole_back_gp = new GraphicsPath();
                    if (ishorizontal)
                    {
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Height, this.poleRect.Height), 90, 180);
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.Right - this.poleRect.Height, this.poleRect.Top, this.poleRect.Height, this.poleRect.Height), 270, 180);
                    }
                    else
                    {
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Width, this.poleRect.Width), 180, 180);
                        pole_back_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Bottom - this.poleRect.Width, this.poleRect.Width, this.poleRect.Width), 0, 180);
                    }
                    SolidBrush pole_back_sb = new SolidBrush(pole_back_color);
                    g.FillPath(pole_back_sb, pole_back_gp);
                    pole_back_sb.Dispose();
                    pole_back_gp.Dispose();
                }

                //滑杆值色
                if (this.Track.ValueGradualColors.Count > 0)
                {
                    RectangleF pole_value_sb_rect = RectangleF.Empty;
                    GraphicsPath pole_value_gp = new GraphicsPath();
                    if (ishorizontal)
                    {
                        pole_value_sb_rect = new RectangleF(this.poleRect.X - 1, this.poleRect.Y, this.poleRect.Width + 1, this.poleRect.Height);
                        pole_value_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Height, this.poleRect.Height), 90, 180);
                        pole_value_gp.AddLine(new PointF(this.lumpRect.X + this.lumpRect.Width / 2, this.poleRect.Y), new PointF(this.lumpRect.X + this.lumpRect.Width / 2, this.poleRect.Bottom));
                    }
                    else
                    {
                        pole_value_sb_rect = new RectangleF(this.poleRect.X, this.poleRect.Y - 1, this.poleRect.Width, this.poleRect.Height + 1);
                        pole_value_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Bottom - this.poleRect.Width, this.poleRect.Width, this.poleRect.Width), 0, 180);
                        pole_value_gp.AddLine(new PointF(this.poleRect.X, this.lumpRect.Bottom - this.lumpRect.Height / 2), new PointF(this.poleRect.Right, this.lumpRect.Bottom - this.lumpRect.Height / 2));
                    }

                    LinearGradientBrush pole_value_back_lgb = this.GetLinearGradientBrush(this.Track.ValueGradualColors, pole_value_sb_rect, (ishorizontal ? 0f : 270f));
                    g.FillPath(pole_value_back_lgb, pole_value_gp);
                    pole_value_back_lgb.Dispose();
                    pole_value_gp.Dispose();
                }
                else
                {
                    if (pole_value_color != Color.Empty && pole_value_color.A != 0)
                    {
                        GraphicsPath pole_value_gp = new GraphicsPath();
                        if (ishorizontal)
                        {
                            pole_value_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Height, this.poleRect.Height), 90, 180);
                            pole_value_gp.AddLine(new PointF(this.lumpRect.X + this.lumpRect.Width / 2, this.poleRect.Y), new PointF(this.lumpRect.X + this.lumpRect.Width / 2, this.poleRect.Bottom));
                        }
                        else
                        {
                            pole_value_gp.AddArc(new RectangleF(this.poleRect.X, this.poleRect.Bottom - this.poleRect.Width, this.poleRect.Width, this.poleRect.Width), 0, 180);
                            pole_value_gp.AddLine(new PointF(this.poleRect.X, this.lumpRect.Bottom - this.lumpRect.Height / 2), new PointF(this.poleRect.Right, this.lumpRect.Bottom - this.lumpRect.Height / 2));
                        }
                        SolidBrush pole_value_back_sb = new SolidBrush(pole_value_color);
                        g.FillPath(pole_value_back_sb, pole_value_gp);
                        pole_value_back_sb.Dispose();
                        pole_value_gp.Dispose();
                    }
                }

                //滑块背景
                SolidBrush lump_back_sb = new SolidBrush(lump_back_color);
                g.FillPath(lump_back_sb, this.lumpPath);
                lump_back_sb.Dispose();

                //滑块边框
                Pen lump_border_pen = new Pen(this.StyleAppearance.Normal.ThumbBorderColor);
                g.DrawPath(lump_border_pen, this.lumpPath);
                lump_border_pen.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    RectangleF activate_rectf = new RectangleF(this.lumpRect.X + 3, this.lumpRect.Y + 3, this.lumpRect.Width - 6, this.lumpRect.Height - 6);
                    Pen activate_border_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawEllipse(activate_border_pen, activate_rectf);
                    activate_border_pen.Dispose();
                }

            }
            else if (this.StylePattern == TrackBarPlusStylePattern.Square)
            {
                //滑杆背景色
                if (this.Track.BackGradualColors.Count > 0)
                {
                    RectangleF pole_back_sb_rect = RectangleF.Empty;
                    if (ishorizontal)
                    {
                        pole_back_sb_rect = new RectangleF(this.poleRect.X - 1, this.poleRect.Y, this.poleRect.Width + 1, this.poleRect.Height);
                    }
                    else
                    {
                        pole_back_sb_rect = new RectangleF(this.poleRect.X, this.poleRect.Y - 1, this.poleRect.Width, this.poleRect.Height + 1);
                    }
                    LinearGradientBrush pole_back_lgb = this.GetLinearGradientBrush(this.Track.BackGradualColors, pole_back_sb_rect, (ishorizontal ? 0f : 270f));
                    g.FillRectangle(pole_back_lgb, this.poleRect);
                    pole_back_lgb.Dispose();
                }
                else
                {
                    SolidBrush pole_back_sb = new SolidBrush(pole_back_color);
                    g.FillRectangle(pole_back_sb, this.poleRect);
                    pole_back_sb.Dispose();
                }

                //滑杆值色
                if (this.Track.ValueGradualColors.Count > 0)
                {
                    RectangleF pole_back_sb_rect = RectangleF.Empty;
                    RectangleF pole_value_rect = RectangleF.Empty;
                    if (ishorizontal)
                    {
                        pole_back_sb_rect = new RectangleF(this.poleRect.X - 1, this.poleRect.Y, this.poleRect.Width + 1, this.poleRect.Height);
                        pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, (this.lumpRect.X + this.lumpRect.Width / 2 - this.poleRect.X), this.poleRect.Height);
                    }
                    else
                    {
                        pole_back_sb_rect = new RectangleF(this.poleRect.X, this.poleRect.Y - 1, this.poleRect.Width, this.poleRect.Height + 1);
                        pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Width, (this.lumpRect.Y + this.lumpRect.Height / 2 - this.poleRect.Y));
                    }

                    LinearGradientBrush pole_value_back_lgb = this.GetLinearGradientBrush(this.Track.ValueGradualColors, pole_back_sb_rect, (ishorizontal ? 0f : 270f));
                    g.FillRectangle(pole_value_back_lgb, pole_value_rect);
                    pole_value_back_lgb.Dispose();
                }
                else
                {
                    if (pole_value_color != Color.Empty && pole_value_color.A != 0)
                    {
                        RectangleF pole_value_rect = RectangleF.Empty;
                        if (ishorizontal)
                        {
                            pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, (this.lumpRect.X + this.lumpRect.Width / 2 - this.poleRect.X), this.poleRect.Height);
                        }
                        else
                        {
                            pole_value_rect = new RectangleF(this.poleRect.X, this.poleRect.Y, this.poleRect.Width, (this.lumpRect.Y + this.lumpRect.Height / 2 - this.poleRect.Y));
                        }
                        SolidBrush pole_value_back_sb = new SolidBrush(pole_value_color);
                        g.FillRectangle(pole_value_back_sb, pole_value_rect);
                        pole_value_back_sb.Dispose();
                    }
                }

                //滑块背景
                SolidBrush lump_back_sb = new SolidBrush(lump_back_color);
                g.FillRectangle(lump_back_sb, this.lumpRect);
                lump_back_sb.Dispose();

                //滑块边框
                Pen lump_border_pen = new Pen(this.StyleAppearance.Normal.ThumbBorderColor);
                g.DrawRectangle(lump_border_pen, this.lumpRect.X, this.lumpRect.Y, this.lumpRect.Width, this.lumpRect.Height);
                lump_border_pen.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    Pen activate_border_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawRectangle(activate_border_pen, this.lumpRect.X + 3, this.lumpRect.Y + 3, this.lumpRect.Width - 6, this.lumpRect.Height - 6);
                    activate_border_pen.Dispose();
                }

            }

            //刻度线
            if (this.Mark.Visible)
            {
                g.SmoothingMode = SmoothingMode.Default;
                g.InterpolationMode = InterpolationMode.Default;

                decimal maxminvalue_scope = (decimal)this.MaxValue - (decimal)this.MinValue;
                int line_count = (int)Math.Ceiling(maxminvalue_scope / (decimal)this.mark.LineFrequency);
                Pen mark_line_pen = new Pen(mark_line_color, this.Mark.LineBold ? 2 : 1);

                if (ishorizontal)
                {
                    float tmp = ((this.Lump_End_Point - this.Lump_Start_Point) / (float)maxminvalue_scope) * (float)this.Mark.LineFrequency;//单位刻度占用像素
                    float y_start = this.lumpRect.Y - 2;
                    float y_end = content_rect.Y;
                    if (this.Orientation == TrackBarPlusOrientation.HorizontalBottom)
                    {
                        y_start = this.lumpRect.Bottom + 2;
                        y_end = content_rect.Bottom;
                    }
                    for (int i = 0; i < line_count; i++)
                    {
                        float x = this.Lump_Start_Point + i * tmp;
                        g.DrawLine(mark_line_pen, new PointF(x, y_start), new PointF(x, y_end));
                    }
                    if (maxminvalue_scope / (decimal)this.Mark.LineFrequency != 0)
                    {
                        g.DrawLine(mark_line_pen, new PointF(this.Lump_End_Point, y_start), new PointF(this.Lump_End_Point, y_end));
                    }
                }
                else
                {
                    float tmp = ((this.Lump_Start_Point - this.Lump_End_Point) / (float)maxminvalue_scope) * (float)this.Mark.LineFrequency;//单位刻度占用像素
                    float x_start = this.lumpRect.X - 2;
                    float x_end = content_rect.X;
                    if (this.Orientation == TrackBarPlusOrientation.VerticalRight)
                    {
                        x_start = this.lumpRect.Right + 2;
                        x_end = content_rect.Right;
                    }
                    for (int i = 0; i < line_count; i++)
                    {
                        float y = this.Lump_Start_Point - i * tmp;
                        g.DrawLine(mark_line_pen, new PointF(x_start, y), new PointF(x_end, y));
                    }
                    if (maxminvalue_scope / (decimal)this.Mark.LineFrequency != 0)
                    {
                        g.DrawLine(mark_line_pen, new PointF(x_start, this.Lump_End_Point), new PointF(x_end, this.Lump_End_Point));
                    }
                }
                mark_line_pen.Dispose();
            }

        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            this.mousedownobject = false;
            this.mousedownobjectvalue = -1;
            this.mousedownpoint = Point.Empty;
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!this.Enabled)
            {
                this.mousedownobject = false;
                this.mousedownobjectvalue = -1;
                this.mousedownpoint = Point.Empty;
                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (!this.Visible)
            {
                this.mousedownobject = false;
                this.mousedownobjectvalue = -1;
                this.mousedownpoint = Point.Empty;
                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.Parent == null)
            {
                this.mousedownobject = false;
                this.mousedownobjectvalue = -1;
                this.mousedownpoint = Point.Empty;
                this.Invalidate();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (!this.Focused)
            {
                this.Focus();
            }

            if (e.Button == MouseButtons.Left && this.MaxValue != this.MinValue)
            {
                if (
                    (this.StylePattern == TrackBarPlusStylePattern.Square && this.lumpRect.Contains(e.Location)) ||
                     (this.StylePattern != TrackBarPlusStylePattern.Square && this.lumpPath.IsVisible(e.Location))
                    )
                {
                    this.mousedownobject = true;
                    this.mousedownobjectvalue = (decimal)this.Value;
                    this.mousedownpoint = e.Location;
                }
                else if (this.Track.ClickChange && new RectangleF(this.poleRect.X, this.poleRect.Y - (this.lumpRect.Height - this.poleRect.Height) / 2, this.poleRect.Width, this.lumpRect.Height).Contains(e.Location))
                {
                    bool ishorizontal = (this.Orientation == TrackBarPlusOrientation.HorizontalTop || this.Orientation == TrackBarPlusOrientation.HorizontalBottom);
                    int scale_contentPadding = (int)Math.Ceiling(this.contentPadding * this.ScaleDpi);
                    Rectangle content_rect = new Rectangle(scale_contentPadding, scale_contentPadding, this.ClientRectangle.Width - scale_contentPadding * 2, this.ClientRectangle.Height - scale_contentPadding * 2);
                    decimal maxminvalue_scope = (decimal)this.MaxValue - (decimal)this.MinValue;
                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);

                    float scale_lumpRadius = ishorizontal ? this.lumpRect.Width / 2 : this.lumpRect.Height / 2;
                    decimal allow_track_pixel_scope = (decimal)(ishorizontal ? this.Lump_End_Point - this.Lump_Start_Point : this.Lump_Start_Point - this.Lump_End_Point);
                    decimal mouse_offset = ishorizontal ? ((decimal)(e.Location.X - (this.lumpRect.X + scale_lumpRadius))) : (-(decimal)(e.Location.Y - (this.lumpRect.Bottom - scale_lumpRadius)));
                    decimal value_offset = mouse_offset / allow_track_pixel_scope * maxminvalue_scope;
                    value_offset = ((int)Math.Ceiling(Math.Abs(value_offset) / smallchange_tmp)) * smallchange_tmp * (value_offset > 0 ? 1 : -1);//保证移动为单位最小移动间隔

                    decimal value_tmp = (decimal)this.Value + value_offset;
                    value_tmp = Math.Max((decimal)this.MinValue, value_tmp);
                    value_tmp = Math.Min((decimal)this.MaxValue, value_tmp);
                    this.Value = (double)value_tmp;
                }
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            this.mousedownobject = false;
            this.mousedownobjectvalue = -1;
            this.mousedownpoint = Point.Empty;

            base.OnMouseUp(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (!(
                this.mousedownobject == false ||
                ((this.Orientation == TrackBarPlusOrientation.HorizontalTop || this.Orientation == TrackBarPlusOrientation.HorizontalBottom) && e.Location.X == this.mousedownpoint.X) ||
                ((this.Orientation == TrackBarPlusOrientation.VerticalLeft || this.Orientation == TrackBarPlusOrientation.VerticalRight) && e.Location.Y == this.mousedownpoint.Y)
                ))
            {
                bool ishorizontal = (this.Orientation == TrackBarPlusOrientation.HorizontalTop || this.Orientation == TrackBarPlusOrientation.HorizontalBottom);
                int scale_contentPadding = (int)Math.Ceiling(this.contentPadding * this.ScaleDpi);
                Rectangle content_rect = new Rectangle(scale_contentPadding, scale_contentPadding, this.ClientRectangle.Width - scale_contentPadding * 2, this.ClientRectangle.Height - scale_contentPadding * 2);
                decimal maxminvalue_scope = (decimal)this.MaxValue - (decimal)this.MinValue;
                decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);

                decimal allow_track_pixel_scope = (decimal)(ishorizontal ? this.Lump_End_Point - this.Lump_Start_Point : this.Lump_Start_Point - this.Lump_End_Point);
                decimal mouse_offset = ishorizontal ? ((decimal)(e.Location.X - this.mousedownpoint.X)) : (-(decimal)(e.Location.Y - this.mousedownpoint.Y));
                decimal value_offset = mouse_offset / allow_track_pixel_scope * maxminvalue_scope;

                decimal value_tmp = this.mousedownobjectvalue + (int)(Math.Abs(value_offset) / smallchange_tmp) * smallchange_tmp * (mouse_offset > 0 ? 1 : -1);//保证移动为单位最小移动间隔
                if (Math.Abs(value_offset) % smallchange_tmp >= smallchange_tmp / 2)
                {
                    value_tmp += (mouse_offset > 0 ? smallchange_tmp : -smallchange_tmp);
                }
                if (value_tmp % smallchange_tmp != 0)//保证值最后在单位最小移动间隔上
                {
                    value_tmp += (mouse_offset > 0 ? Math.Abs(value_tmp % smallchange_tmp) : -Math.Abs(value_tmp % smallchange_tmp));
                }
                value_tmp = Math.Min(value_tmp, (decimal)this.MaxValue);
                value_tmp = Math.Max(value_tmp, (decimal)this.MinValue);
                if ((decimal)this.Value != value_tmp)
                {
                    this.Value = (double)value_tmp;
                }
            }

        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Right:
                case Keys.Up:
                    {
                        this.Value = (double)Math.Min((decimal)this.MaxValue, (decimal)this.Value + (decimal)this.SmallChange);

                        return true;
                    }
                case Keys.Left:
                case Keys.Down:
                    {
                        this.Value = (double)Math.Max((decimal)this.MinValue, (decimal)this.Value - (decimal)this.SmallChange);

                        return true;
                    }

            }

            return base.ProcessDialogKey(keyData);
        }

        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            int tmp = this.GetControlAutoHeight();
            if (this.Orientation == TrackBarPlusOrientation.HorizontalTop || this.Orientation == TrackBarPlusOrientation.HorizontalBottom)
            {
                height = tmp;
            }
            else
            {
                width = tmp;
            }

            base.SetBoundsCore(x, y, width, height, specified);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            this.InitializeElement();
            this.Invalidate();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.lumpPath != null)
                {
                    lumpPath.Dispose();
                    this.lumpPath = null;
                }
            }
            base.Dispose(disposing);
        }

        #endregion

        #region 虚方法

        protected virtual void OnValueChanged(EventArgs e)
        {
            EventHandler handler = Events[EventValueChanged] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {
            int scale_contentPadding = (int)Math.Ceiling(this.contentPadding * this.ScaleDpi);
            Rectangle content_rect = new Rectangle(scale_contentPadding, scale_contentPadding, this.ClientRectangle.Width - scale_contentPadding * 2, this.ClientRectangle.Height - scale_contentPadding * 2);
            int scale_markLineThickness = this.Mark.Visible ? (int)Math.Ceiling(this.Mark.LineThickness * this.ScaleDpi) : 0;
            int scale_poleRadius = (int)(Math.Ceiling(this.Track.Thickness * this.ScaleDpi) / 2);
            int scale_poleDiameter = scale_poleRadius * 2;
            decimal maxminvalue_scope = (decimal)this.MaxValue - (decimal)this.MinValue;

            if (this.StylePattern == TrackBarPlusStylePattern.Excircle)
            {
                int scale_lumpRadius = (int)Math.Ceiling(this.Thumb.Diameter * this.ScaleDpi) / 2;
                int scale_lumpDiameter = scale_lumpRadius * 2;

                if (this.Orientation == TrackBarPlusOrientation.HorizontalTop)
                {
                    this.Lump_Start_Point = content_rect.X + scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Right - scale_lumpRadius;

                    this.poleRect = new RectangleF(this.Lump_Start_Point, content_rect.Y + scale_markLineThickness + scale_lumpRadius - scale_poleRadius, this.Lump_End_Point - this.Lump_Start_Point, scale_poleDiameter);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_End_Point - this.Lump_Start_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_x = this.Lump_Start_Point + (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_x = Math.Max(lump_current_x, this.Lump_Start_Point);
                    lump_current_x = Math.Min(lump_current_x, this.Lump_End_Point);
                    this.lumpRect = new RectangleF(lump_current_x - scale_lumpRadius, content_rect.Y + scale_markLineThickness, scale_lumpDiameter, scale_lumpDiameter);
                }
                else if (this.Orientation == TrackBarPlusOrientation.HorizontalBottom)
                {
                    this.Lump_Start_Point = content_rect.X + scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Right - scale_lumpRadius;

                    this.poleRect = new RectangleF(this.Lump_Start_Point, content_rect.Bottom - scale_markLineThickness - scale_lumpRadius - scale_poleRadius, this.Lump_End_Point - this.Lump_Start_Point, scale_poleDiameter);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_End_Point - this.Lump_Start_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_x = this.Lump_Start_Point + (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_x = Math.Max(lump_current_x, this.Lump_Start_Point);
                    lump_current_x = Math.Min(lump_current_x, this.Lump_End_Point);
                    this.lumpRect = new RectangleF(lump_current_x - scale_lumpRadius, content_rect.Bottom - scale_markLineThickness - scale_lumpDiameter, scale_lumpDiameter, scale_lumpDiameter);
                }
                else if (this.Orientation == TrackBarPlusOrientation.VerticalLeft)
                {
                    this.Lump_Start_Point = content_rect.Bottom - scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Y + scale_lumpRadius;

                    this.poleRect = new RectangleF(content_rect.X + scale_markLineThickness + scale_lumpRadius - scale_poleRadius, this.Lump_End_Point, scale_poleDiameter, this.Lump_Start_Point - this.Lump_End_Point);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_Start_Point - this.Lump_End_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_y = this.Lump_Start_Point - (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_y = Math.Max(lump_current_y, this.Lump_End_Point);
                    lump_current_y = Math.Min(lump_current_y, this.Lump_Start_Point);
                    this.lumpRect = new RectangleF(content_rect.X + scale_markLineThickness, lump_current_y - scale_lumpRadius, scale_lumpDiameter, scale_lumpDiameter);
                }
                else if (this.Orientation == TrackBarPlusOrientation.VerticalRight)
                {
                    this.Lump_Start_Point = content_rect.Bottom - scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Y + scale_lumpRadius;

                    this.poleRect = new RectangleF(content_rect.Right - scale_markLineThickness - scale_lumpRadius - scale_poleRadius, this.Lump_End_Point, scale_poleDiameter, this.Lump_Start_Point - this.Lump_End_Point);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_Start_Point - this.Lump_End_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_y = this.Lump_Start_Point - (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_y = Math.Max(lump_current_y, this.Lump_End_Point);
                    lump_current_y = Math.Min(lump_current_y, this.Lump_Start_Point);
                    this.lumpRect = new RectangleF(content_rect.Right - scale_markLineThickness - scale_lumpDiameter, lump_current_y - scale_lumpRadius, scale_lumpDiameter, scale_lumpDiameter);
                }

                GraphicsPath lumppath_tmp = this.lumpPath;
                this.lumpPath = new GraphicsPath();
                this.lumpPath.AddEllipse(this.lumpRect);
                if (lumppath_tmp != null)
                {
                    lumppath_tmp.Dispose();
                }
            }
            else if (this.StylePattern == TrackBarPlusStylePattern.InnerCircle)
            {
                int scale_lumpRadius = scale_poleRadius;
                int scale_lumpDiameter = scale_lumpRadius * 2;

                if (this.Orientation == TrackBarPlusOrientation.HorizontalTop)
                {
                    this.Lump_Start_Point = content_rect.X + scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Right - scale_lumpRadius;

                    this.poleRect = new RectangleF(content_rect.X, content_rect.Y + scale_markLineThickness, content_rect.Width, scale_poleDiameter);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_End_Point - this.Lump_Start_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_x = this.Lump_Start_Point + (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_x = Math.Max(lump_current_x, this.Lump_Start_Point);
                    lump_current_x = Math.Min(lump_current_x, this.Lump_End_Point);
                    this.lumpRect = new RectangleF(lump_current_x - scale_lumpRadius, content_rect.Y + scale_markLineThickness, scale_lumpDiameter, scale_lumpDiameter);
                }
                else if (this.Orientation == TrackBarPlusOrientation.HorizontalBottom)
                {
                    this.Lump_Start_Point = content_rect.X + scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Right - scale_lumpRadius;

                    this.poleRect = new RectangleF(content_rect.X, content_rect.Bottom - scale_markLineThickness - scale_lumpDiameter, content_rect.Width, scale_poleDiameter);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_End_Point - this.Lump_Start_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_x = this.Lump_Start_Point + (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_x = Math.Max(lump_current_x, this.Lump_Start_Point);
                    lump_current_x = Math.Min(lump_current_x, this.Lump_End_Point);
                    this.lumpRect = new RectangleF(lump_current_x - scale_lumpRadius, content_rect.Bottom - scale_markLineThickness - scale_lumpDiameter, scale_lumpDiameter, scale_lumpDiameter);
                }
                else if (this.Orientation == TrackBarPlusOrientation.VerticalLeft)
                {
                    this.Lump_Start_Point = content_rect.Bottom - scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Y + scale_lumpRadius;

                    this.poleRect = new RectangleF(content_rect.X + scale_markLineThickness, content_rect.Y, scale_poleDiameter, content_rect.Height);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_Start_Point - this.Lump_End_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_y = this.Lump_Start_Point - (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_y = Math.Max(lump_current_y, this.Lump_End_Point);
                    lump_current_y = Math.Min(lump_current_y, this.Lump_Start_Point);
                    this.lumpRect = new RectangleF(content_rect.X + scale_markLineThickness, lump_current_y - scale_lumpRadius, scale_lumpDiameter, scale_lumpDiameter);
                }
                else if (this.Orientation == TrackBarPlusOrientation.VerticalRight)
                {
                    this.Lump_Start_Point = content_rect.Bottom - scale_lumpRadius;
                    this.Lump_End_Point = content_rect.Y + scale_lumpRadius;

                    this.poleRect = new RectangleF(content_rect.Right - scale_markLineThickness - scale_lumpDiameter, content_rect.Y, scale_poleDiameter, content_rect.Height);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_Start_Point - this.Lump_End_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_y = this.Lump_Start_Point - (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_y = Math.Max(lump_current_y, this.Lump_End_Point);
                    lump_current_y = Math.Min(lump_current_y, this.Lump_Start_Point);
                    this.lumpRect = new RectangleF(content_rect.Right - scale_markLineThickness - scale_lumpDiameter, lump_current_y - scale_lumpRadius, scale_lumpDiameter, scale_lumpDiameter);
                }

                GraphicsPath lumppath_tmp = this.lumpPath;
                this.lumpPath = new GraphicsPath();
                this.lumpPath.AddEllipse(this.lumpRect);
                if (lumppath_tmp != null)
                {
                    lumppath_tmp.Dispose();
                }
            }
            else if (this.StylePattern == TrackBarPlusStylePattern.Square)
            {
                int scale_lumpHeightRadius = (int)(Math.Ceiling(this.Thumb.Diameter * this.ScaleDpi) / 2f);
                int scale_lumpHeight = scale_lumpHeightRadius * 2;
                int scale_lumpWidthRadius = (int)Math.Ceiling(scale_lumpHeight / 5f);
                int scale_lumpWidth = scale_lumpWidthRadius * 2;

                if (this.Orientation == TrackBarPlusOrientation.HorizontalTop)
                {
                    this.Lump_Start_Point = content_rect.X + scale_lumpWidthRadius;
                    this.Lump_End_Point = content_rect.Right - scale_lumpWidthRadius;

                    this.poleRect = new RectangleF(content_rect.X, content_rect.Y + scale_markLineThickness + scale_lumpHeightRadius - scale_poleRadius, content_rect.Width, scale_poleDiameter);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_End_Point - this.Lump_Start_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_x = this.Lump_Start_Point + (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_x = Math.Max(lump_current_x, this.Lump_Start_Point);
                    lump_current_x = Math.Min(lump_current_x, this.Lump_End_Point);
                    this.lumpRect = new RectangleF(lump_current_x - scale_lumpWidthRadius, content_rect.Y + scale_markLineThickness, scale_lumpWidth, scale_lumpHeight);
                }
                else if (this.Orientation == TrackBarPlusOrientation.HorizontalBottom)
                {
                    this.Lump_Start_Point = content_rect.X + scale_lumpWidthRadius;
                    this.Lump_End_Point = content_rect.Right - scale_lumpWidthRadius;

                    this.poleRect = new RectangleF(content_rect.X, content_rect.Bottom - scale_markLineThickness - scale_lumpHeightRadius - scale_poleRadius, content_rect.Width, scale_poleDiameter);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_End_Point - this.Lump_Start_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_x = this.Lump_Start_Point + (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_x = Math.Max(lump_current_x, this.Lump_Start_Point);
                    lump_current_x = Math.Min(lump_current_x, this.Lump_End_Point);
                    this.lumpRect = new RectangleF(lump_current_x - scale_lumpWidthRadius, content_rect.Bottom - scale_markLineThickness - scale_lumpHeight, scale_lumpWidth, scale_lumpHeight);
                }
                else if (this.Orientation == TrackBarPlusOrientation.VerticalLeft)
                {
                    this.Lump_Start_Point = content_rect.Bottom - scale_lumpWidthRadius;
                    this.Lump_End_Point = content_rect.Y + scale_lumpWidthRadius;

                    this.poleRect = new RectangleF(content_rect.X + scale_markLineThickness + scale_lumpHeightRadius - scale_poleRadius, content_rect.Y, scale_poleDiameter, content_rect.Height);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_Start_Point - this.Lump_End_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_y = this.Lump_Start_Point - (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_y = Math.Max(lump_current_y, this.Lump_End_Point);
                    lump_current_y = Math.Min(lump_current_y, this.Lump_Start_Point);
                    this.lumpRect = new RectangleF(content_rect.X + scale_markLineThickness, lump_current_y - scale_lumpWidthRadius, scale_lumpHeight, scale_lumpWidth);
                }
                else if (this.Orientation == TrackBarPlusOrientation.VerticalRight)
                {
                    this.Lump_Start_Point = content_rect.Bottom - scale_lumpWidthRadius;
                    this.Lump_End_Point = content_rect.Y + scale_lumpWidthRadius;

                    this.poleRect = new RectangleF(content_rect.Right - scale_markLineThickness - scale_lumpHeightRadius - scale_poleRadius, content_rect.Y, scale_poleDiameter, content_rect.Height);

                    decimal smallchange_tmp = Math.Min((decimal)this.SmallChange, maxminvalue_scope);
                    decimal smallvalue_representative_pixel = (smallchange_tmp == 0) ? 0 : (decimal)(this.Lump_Start_Point - this.Lump_End_Point) / (maxminvalue_scope / smallchange_tmp);//单位最小移动间隔代表多少个像素
                    float lump_current_y = this.Lump_Start_Point - (smallchange_tmp == 0 ? 0 : (float)(((decimal)this.Value - (decimal)this.minValue) / smallchange_tmp * smallvalue_representative_pixel));
                    lump_current_y = Math.Max(lump_current_y, this.Lump_End_Point);
                    lump_current_y = Math.Min(lump_current_y, this.Lump_Start_Point);
                    this.lumpRect = new RectangleF(content_rect.Right - scale_markLineThickness - scale_lumpHeight, lump_current_y - scale_lumpWidthRadius, scale_lumpHeight, scale_lumpWidth);
                }
            }

        }

        #endregion 

        #region 私有方法

        /// <summary>
        /// 根据设置计算控件高度
        /// </summary>
        /// <returns></returns>
        private int GetControlAutoHeight()
        {
            int height = 0;

            int scale_markLineThickness = this.Mark.Visible ? (int)Math.Ceiling(this.Mark.LineThickness * this.ScaleDpi) : 0;
            int scale_contentPadding = (int)Math.Ceiling(this.contentPadding * this.ScaleDpi);
            Rectangle content_rect = new Rectangle(scale_contentPadding, scale_contentPadding, this.ClientRectangle.Width - scale_contentPadding * 2, this.ClientRectangle.Height - scale_contentPadding * 2);

            if (this.StylePattern == TrackBarPlusStylePattern.Excircle)
            {
                height = scale_contentPadding * 2 + scale_markLineThickness + (int)Math.Ceiling(this.Thumb.Diameter * this.ScaleDpi);
            }
            else if (this.StylePattern == TrackBarPlusStylePattern.InnerCircle)
            {
                height = scale_contentPadding * 2 + scale_markLineThickness + (int)Math.Ceiling(this.Track.Thickness * this.ScaleDpi);
            }
            else if (this.StylePattern == TrackBarPlusStylePattern.Square)
            {
                height = scale_contentPadding * 2 + scale_markLineThickness + (int)Math.Ceiling(this.Thumb.Diameter * this.ScaleDpi);
            }

            return height;
        }

        /// <summary>
        /// 自动根据设置更新控件Size
        /// </summary>
        private void UpdateAutoControlSize()
        {
            int height = this.GetControlAutoHeight();
            int width = 0;
            if (this.Orientation == TrackBarPlusOrientation.HorizontalTop || this.Orientation == TrackBarPlusOrientation.HorizontalBottom)
            {
                width = (this.Height > this.Width) ? this.Height : this.Width;
                this.Size = new Size(width, height);
            }
            else
            {
                width = (this.Width > this.Height) ? this.Width : this.Height;
                this.Size = new Size(height, width);
            }
        }

        /// <summary>
        /// 获取渐变画笔
        /// </summary>
        /// <param name="list">渐变颜色集合</param>
        /// <param name="rect">要渐变区域</param>
        /// <param name="angle">渐变角度</param>
        /// <returns></returns>
        private LinearGradientBrush GetLinearGradientBrush(TrackBarPlusGradualColorCollection list, RectangleF rect, float angle)
        {
            if (list.Count == 0)
            {
                return null;
            }

            int len = Math.Max(2, list.Count);
            Color[] colors = new Color[len];
            float[] positions = new float[len];
            for (int i = 0; i < list.Count; i++)
            {
                colors[i] = list[i].Color;
                if (i == 0)
                {
                    positions[i] = 0;
                }
                else if (i == len - 1)
                {
                    positions[i] = 1;
                }
                else
                {
                    positions[i] = list[i].Position;
                }
            }
            if (list.Count == 1)
            {
                colors[len - 1] = list[0].Color;
                positions[len - 1] = 1;
            }

            return new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, angle, true) { InterpolationColors = new ColorBlend() { Positions = positions, Colors = colors } };

        }

        #endregion

        #region 类

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class TrackObject
        {
            private TrackBarPlus owner = null;
            internal TrackObject(TrackBarPlus owner) { this.owner = owner; }

            #region 属性

            private int thickness = 4;
            /// <summary>
            /// 轨道厚度
            /// </summary>
            [Description("轨道厚度")]
            [PropertyOrder(-170)]
            [DefaultValue(4)]
            public int Thickness
            {
                get { return this.thickness; }
                set
                {
                    if (this.thickness == value || value < 0)
                        return;

                    this.thickness = value;
                    if ((((TrackBarPlus)this.owner).StylePattern == TrackBarPlusStylePattern.Excircle || ((TrackBarPlus)this.owner).StylePattern == TrackBarPlusStylePattern.Square) && ((TrackBarPlus)this.owner).Thumb.Diameter < value)
                    {
                        ((TrackBarPlus)this.owner).Thumb.Diameter = value;
                    }
                    ((TrackBarPlus)this.owner).UpdateAutoControlSize();
                    if (this.owner != null)
                    {
                        this.owner.InitializeElement();
                        this.owner.Invalidate();
                    }
                }
            }

            private TrackBarPlusGradualColorCollection backGradualColorsCollection;
            /// <summary>
            /// 轨道背景渐变颜色集合
            /// </summary>
            [Description("轨道背景渐变颜色集合")]
            [PropertyOrder(-166)]
            [DefaultValue(null)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            public TrackBarPlusGradualColorCollection BackGradualColors
            {
                get
                {
                    if (this.backGradualColorsCollection == null)
                        this.backGradualColorsCollection = new TrackBarPlusGradualColorCollection(((TrackBarPlus)this.owner));
                    return this.backGradualColorsCollection;
                }
            }

            private TrackBarPlusGradualColorCollection valueGradualColorsCollection;
            /// <summary>
            /// 轨道值渐变颜色集合
            /// </summary>
            [Description("轨道值渐变颜色集合")]
            [PropertyOrder(-163)]
            [DefaultValue(null)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            public TrackBarPlusGradualColorCollection ValueGradualColors
            {
                get
                {
                    if (this.valueGradualColorsCollection == null)
                        this.valueGradualColorsCollection = new TrackBarPlusGradualColorCollection(((TrackBarPlus)this.owner));
                    return this.valueGradualColorsCollection;
                }
            }

            private bool clickChange = false;
            /// <summary>
            /// 是否启用鼠标单击轨道修改值功能
            /// </summary>
            [Description("是否启用鼠标单击轨道修改值功能")]
            [PropertyOrder(-160)]
            [DefaultValue(false)]
            public bool ClickChange
            {
                get { return this.clickChange; }
                set
                {
                    if (this.clickChange == value)
                        return;

                    this.clickChange = value;
                }
            }

            #endregion

        }

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class ThumbObject
        {
            private TrackBarPlus owner = null;
            internal ThumbObject(TrackBarPlus owner) { this.owner = owner; }

            #region 属性

            private int diameter = 18;
            /// <summary>
            /// 拇指直径 (只限于 Excircle、Square 风格)
            /// </summary>
            [Description("拇指直径 (只限于 Excircle、Square 风格)")]
            [PropertyOrder(-158)]
            [DefaultValue(18)]
            public int Diameter
            {
                get { return this.diameter; }
                set
                {
                    if (this.diameter == value || value <= 0)
                        return;

                    if (value < ((TrackBarPlus)this.owner).Track.Thickness)
                    {
                        value = ((TrackBarPlus)this.owner).Track.Thickness;
                    }

                    this.diameter = value;
                    ((TrackBarPlus)this.owner).UpdateAutoControlSize();
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class MarkObject
        {
            private TrackBarPlus owner = null;
            internal MarkObject(TrackBarPlus owner) { this.owner = owner; }

            #region 属性

            private bool visible = false;
            /// <summary>
            /// 是否显示刻度
            /// </summary>
            [Description("是否显示刻度")]
            [PropertyOrder(-140)]
            [DefaultValue(false)]
            public bool Visible
            {
                get { return this.visible; }
                set
                {
                    if (this.visible == value)
                        return;


                    this.visible = value;
                    ((TrackBarPlus)this.owner).UpdateAutoControlSize();
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private int lineThickness = 6;
            /// <summary>
            /// 刻度线厚度
            /// </summary>
            [Description("刻度线厚度")]
            [PropertyOrder(-138)]
            [DefaultValue(6)]
            public int LineThickness
            {
                get { return this.lineThickness; }
                set
                {
                    if (this.lineThickness == value)
                        return;

                    this.lineThickness = value;
                    ((TrackBarPlus)this.owner).UpdateAutoControlSize();
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private bool lineBold = false;
            /// <summary>
            /// 刻度线是否加粗
            /// </summary>
            [Description("刻度线是否加粗")]
            [PropertyOrder(-136)]
            [DefaultValue(false)]
            public bool LineBold
            {
                get { return this.lineBold; }
                set
                {
                    if (this.lineBold == value)
                        return;

                    this.lineBold = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private double lineFrequency = 10;
            /// <summary>
            /// 刻度线间隔值
            /// </summary>
            [Description("刻度线间隔值")]
            [PropertyOrder(-132)]
            [DefaultValue(10D)]
            public double LineFrequency
            {
                get { return this.lineFrequency; }
                set
                {
                    if (this.lineFrequency == value)
                        return;

                    this.lineFrequency = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinActivateColor = Color.Empty;
            private readonly Color defaultActivateColor = SystemColors.Window;
            private Color activateColor = Color.Empty;
            /// <summary>
            /// 控件激活的虚线框颜色
            /// </summary>
            [Description("控件激活的虚线框颜色")]
            [PropertyOrder(-200)]
            [SkinProperty(true, false)]
            public Color ActivateColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinActivateColor;
                    }

                    if (this.activateColor != Color.Empty)
                    {
                        return this.activateColor;
                    }

                    return this.defaultActivateColor;
                }
                set
                {
                    if (this.activateColor == value)
                        return;

                    this.activateColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeActivateColor()
            {
                return this.activateColor != Color.Empty;
            }
            private void ResetActivateColor()
            {
                this.activateColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinBackColor = Color.Empty;
            private readonly Color defaultBackColor = SystemColors.Control;
            private Color backColor = Color.Empty;
            /// <summary>
            /// 背景颜色
            /// </summary>
            [Description("背景颜色")]
            [PropertyOrder(-195)]
            [SkinProperty(true, true)]
            public Color BackColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore() && this.skinBackColor != Color.Empty)
                    {
                        return this.skinBackColor;
                    }

                    if (this.backColor != Color.Empty)
                    {
                        return this.backColor;
                    }

                    if (((Control)this.owner).Parent != null)
                    {
                        return ((Control)this.owner).Parent.BackColor;
                    }

                    return this.defaultBackColor;
                }
                set
                {
                    if (this.backColor == value)
                        return;

                    this.backColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeBackColor()
            {
                return this.backColor != Color.Empty;
            }
            private void ResetBackColor()
            {
                this.backColor = Color.Empty;
                this.Invalidate();
            }

            private ItemAppearanceObject normal;
            /// <summary>
            /// 正常状态
            /// </summary>
            [Description("正常状态")]
            [PropertyOrder(-194)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ItemAppearanceObject Normal
            {
                get
                {
                    if (this.normal == null)
                        this.normal = new ItemAppearanceObject(this.owner, this, SystemColors.GradientInactiveCaption, SystemColors.GradientActiveCaption, SystemColors.ActiveCaption, SystemColors.GradientActiveCaption, SystemColors.ActiveCaption);
                    return this.normal;
                }
            }

            private ItemAppearanceObject disabled;
            /// <summary>
            /// 禁用状态
            /// </summary>
            [Description("禁用状态")]
            [PropertyOrder(-190)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ItemAppearanceObject Disabled
            {
                get
                {
                    if (this.disabled == null)
                        this.disabled = new ItemAppearanceObject(this.owner, this, SystemColors.InactiveCaption, SystemColors.InactiveCaption, SystemColors.InactiveCaption, SystemColors.InactiveCaption, SystemColors.InactiveCaption);
                    return this.disabled;
                }
            }

            #endregion

            public class ItemAppearanceObject : AppearanceObjectBase
            {
                internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color trackBackColor, Color trackValueColor, Color thumbBorderColor, Color thumbBackColor, Color markLineColor) : base(owner, parent)
                {
                    this.defaultTrackBackColor = trackBackColor;
                    this.defaultTrackValueColor = trackValueColor;
                    this.defaultThumbBorderColor = thumbBorderColor;
                    this.defaultThumbBackColor = thumbBackColor;
                    this.defaultMarkLineColor = markLineColor;
                }

                #region 属性

                private Color skinTrackBackColor = Color.Empty;
                private Color defaultTrackBackColor = Color.Empty;
                private Color trackBackColor = Color.Empty;
                /// <summary>
                /// 轨道背景颜色
                /// </summary>
                [Description("轨道背景颜色")]
                [PropertyOrder(-168)]
                [SkinProperty(true, false)]
                public Color TrackBackColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinTrackBackColor;
                        }

                        if (this.trackBackColor != Color.Empty)
                        {
                            return this.trackBackColor;
                        }

                        return this.defaultTrackBackColor;
                    }
                    set
                    {
                        if (this.trackBackColor == value)
                            return;

                        this.trackBackColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeTrackBackColor()
                {
                    return this.trackBackColor != this.defaultTrackBackColor;
                }
                private void ResetTrackBackColor()
                {
                    this.trackBackColor = this.defaultTrackBackColor;
                    this.Invalidate();
                }

                private Color skinTrackValueColor = Color.Empty;
                private Color defaultTrackValueColor = Color.Empty;
                private Color trackValueColor = Color.Empty;
                /// <summary>
                /// 轨道值颜色
                /// </summary>
                [Description("轨道值颜色")]
                [PropertyOrder(-166)]
                [SkinProperty(true, false)]
                public Color TrackValueColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinTrackValueColor;
                        }

                        if (this.trackValueColor != Color.Empty)
                        {
                            return this.trackValueColor;
                        }

                        return this.defaultTrackValueColor;
                    }
                    set
                    {
                        if (this.trackValueColor == value)
                            return;

                        this.trackValueColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeTrackValueColor()
                {
                    return this.trackValueColor != Color.Empty;
                }
                private void ResetTrackValueColor()
                {
                    this.trackValueColor = Color.Empty;
                }

                private Color skinThumbBorderColor = Color.Empty;
                private Color defaultThumbBorderColor = Color.Empty;
                private Color thumbBorderColor = Color.Empty;
                /// <summary>
                /// 拇指边框颜色
                /// </summary>
                [Description("拇指边框颜色")]
                [PropertyOrder(-164)]
                [SkinProperty(true, false)]
                public Color ThumbBorderColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinThumbBorderColor;
                        }

                        if (this.thumbBorderColor != Color.Empty)
                        {
                            return this.thumbBorderColor;
                        }

                        return this.defaultThumbBorderColor;
                    }
                    set
                    {
                        if (this.thumbBorderColor == value)
                            return;

                        this.thumbBorderColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeThumbBorderColor()
                {
                    return this.thumbBorderColor != Color.Empty;
                }
                private void ResetThumbBorderColor()
                {
                    this.thumbBorderColor = Color.Empty;
                }

                private Color skinThumbBackColor = Color.Empty;
                private Color defaultThumbBackColor = Color.Empty;
                private Color thumbBackColor = Color.Empty;
                /// <summary>
                /// 拇指背景颜色
                /// </summary>
                [Description("拇指背景颜色")]
                [PropertyOrder(-162)]
                [SkinProperty(true, false)]
                public Color ThumbBackColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinThumbBackColor;
                        }

                        if (this.thumbBackColor != Color.Empty)
                        {
                            return this.thumbBackColor;
                        }

                        return this.defaultThumbBackColor;
                    }
                    set
                    {
                        if (this.thumbBackColor == value)
                            return;

                        this.thumbBackColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeThumbBackColor()
                {
                    return this.thumbBackColor != Color.Empty;
                }
                private void ResetThumbBackColor()
                {
                    this.thumbBackColor = Color.Empty;
                }

                private Color skinMarkLineColor = Color.Empty;
                private Color defaultMarkLineColor = Color.Empty;
                private Color markLineColor = Color.Empty;
                /// <summary>
                /// 刻度线颜色
                /// </summary>
                [Description("刻度线颜色")]
                [PropertyOrder(-160)]
                [SkinProperty(true, false)]
                public Color MarkLineColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinMarkLineColor;
                        }

                        if (this.markLineColor != Color.Empty)
                        {
                            return this.markLineColor;
                        }

                        return this.defaultMarkLineColor;
                    }
                    set
                    {
                        if (this.markLineColor == value)
                            return;

                        this.markLineColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeMarkLineColor()
                {
                    return this.markLineColor != Color.Empty;
                }
                private void ResetMarkLineColor()
                {
                    this.markLineColor = Color.Empty;
                }

                #endregion

            }

        }

        #endregion

    }
}
